<template>
    <el-button v-if="UIAuth._api_admin_file_folder_id_post" :type="type" @click="showUpload">{{title}}</el-button>
    <PElDialog title="上传文件" v-model="showDialog" width="90%" :showTopClose="false">
        <div class="page-action-btn">
            <div>
                <div class="upload-btn">
                    <el-upload :before-upload="beforeUpload" action="" :http-request="()=>false" :show-file-list="false" multiple :limit="100">
                        <el-button size="small" type="primary">选择文件</el-button>
                    </el-upload>
                </div>
            </div>
        </div>
        <div class="p-upload">
            <p-table :data="selectUploadFiles" :subHeight="235" :showPaginate="false" :highlightCurrentRow="false" :checkBox="false">
                <el-table-column label="文件名称" min-width="140">
                    <template v-slot="{row}">
                        {{row.file.name}}
                    </template>
                </el-table-column>
                <el-table-column label="文件大小" width="80">
                    <template v-slot="{row}">
                        {{(row.file.size / 1024 / 1024).toFixed(2)}}MB
                    </template>
                </el-table-column>
                <el-table-column label="上传进度" width="140">
                    <template v-slot="{row}">
                        <el-progress :text-inside="true" :stroke-width="24" :percentage="row.percentage" />
                    </template>
                </el-table-column>
                <el-table-column label="状态" width="90">
                    <template v-slot="{row}">
                        <el-tag v-if="row.status==0" type="warning"> {{row.statusTxt}}</el-tag>
                        <el-tag v-if="row.status==1"> {{row.statusTxt}}</el-tag>
                        <el-tag v-if="row.status==2" type="success"> {{row.statusTxt}}</el-tag>
                        <el-tag v-if="row.status==3" type="danger"> {{row.statusTxt}}</el-tag>
                    </template>
                </el-table-column>
                <el-table-column label="操作" width="120">
                    <template v-slot="{row,$index}">
                        <div class="table-action-btn">
                            <div v-if="row.status==0 || row.status==3" @click="delFile($index)">删除</div>
                            <div v-if="row.status==3" @click="reUpload($index)">重新上传</div>
                        </div>
                    </template>
                </el-table-column>
            </p-table>
        </div>
        <template #footer>
            <el-button :disabled="disabledBtn" @click="close" size="mini">取消</el-button>
            <el-button type="primary" @click="startUpload" :disabled="disabledBtn" size="mini">上传</el-button>
        </template>
    </PElDialog>
</template>

<script lang="ts">
import config from "@/config";
import http from "@/lib/http/http";
import message from "@/lib/message";
import utils from "@/lib/utils";
import { defineComponent, reactive, toRefs } from "vue";
import { useStore } from "vuex";
import PElDialog from "../PElDialog.vue";
import PTable from "../PTable.vue";
/**
 * state 数据类型
 */
interface IState {
    /**
     * 已经选择的准备上传的文件
     */
    selectUploadFiles: any[];
    /**
     * 上传成功的列表
     */
    uploadOkFiles: any[];
    /**
     * 显示上传窗口
     */
    showDialog: boolean;
    /**
     * 是否禁用按钮
     */
    disabledBtn: boolean;
}
export default defineComponent({
    name: "PUpload",
    props: {
        folderId: {
            type: String,
            default: ""
        },
        title: {
            type: String,
            default: "上传文件"
        },
        type: {
            type: String,
            default: "primary"
        }
    },
    components: { PElDialog, PTable },
    emits: ["upload"],
    setup(props, { emit }) {
        const store = useStore();
        const { UIAuth, bodySize } = toRefs(store.state);
        /**
         * 上传文件大小
         */
        const uploadSize = config.uploadSize;
        /**
         * 可上传文件类型
         */
        const fileExt: string[] = config.fileExt;
        const state = reactive<IState>({
            selectUploadFiles: [],
            uploadOkFiles: [],
            showDialog: false,
            disabledBtn: false
        });
        /**
         * 上传文件列表
         */
        function uploadFile(index: number, callback: any = () => false) {
            if (state.selectUploadFiles[index].status == 0 || state.selectUploadFiles[index].status == 3) {
                state.selectUploadFiles[index].statusTxt = "上传中";
                state.selectUploadFiles[index].percentage = 0;
                state.selectUploadFiles[index].status = 1; // 上传中
                http.upload(`/file/${props.folderId}`, {
                    params: { "upload-file": state.selectUploadFiles[index].file },
                    progress: (events: object, percentage: number) => {
                        // state.percentage = percentage;
                        state.selectUploadFiles[index].percentage = percentage;
                    },
                }).then((data: any) => {
                    state.uploadOkFiles.push(data);
                    state.selectUploadFiles[index].statusTxt = "上传成功";
                    state.selectUploadFiles[index].status = 2; // 上传成功
                    callback();
                }).catch((err: any) => {
                    state.selectUploadFiles[index].statusTxt = "上传失败";
                    state.selectUploadFiles[index].status = 3; // 上传失败
                    callback();
                });
            } else {
                callback();
            }
        }
        /**
         * 重新上传
         */
        function reUpload(index: number) {
            uploadFile(index, () => {
                emit("upload", utils.CopyNewObject(state.uploadOkFiles));
                state.uploadOkFiles = [];
                state.disabledBtn = false;
            });
        }
        /**
         * 开始上传文件
         */
        function startUpload() {
            if (state.selectUploadFiles.length <= 0) {
                message.error("请选择要上传的文件");
                return false;
            }
            if (utils.empty(props.folderId)) {
                message.error("请选择要上传到的文件夹");
                return false;
            }
            let index = 0;
            const uploadFunc = () => {
                uploadFile(index, () => {
                    index++;
                    if (index < state.selectUploadFiles.length) {
                        uploadFunc();
                    } else {
                        emit("upload", utils.CopyNewObject(state.uploadOkFiles));
                        state.uploadOkFiles = [];
                        state.disabledBtn = false;
                    }
                });
            };
            state.disabledBtn = true;
            uploadFunc();
        }
        // 选择文件时回调
        function beforeUpload(file: any) {
            // console.log(file);
            if (utils.empty(props.folderId)) {
                message.error("请选择要上传到的文件夹");
                return false;
            }
            if (file.size > uploadSize) {
                message.error(
                    `文件过大，文件大小不能超过 ${(uploadSize / 1024 / 1024).toFixed(2)} MB`
                );
                return false;
            }
            const ext = file.name.substring(file.name.lastIndexOf(".") + 1);
            const index = fileExt.findIndex((i: string) => i === ext);
            if (index < 0) {
                message.error(`不能上传后缀名为 ${ext} 的文件`);
                return false;
            }
            state.selectUploadFiles.push({ file, percentage: 0, statusTxt: "等待上传", status: 0 });
            return true;
        }
        function close() {
            if (state.disabledBtn) {
                return false;
            }
            state.showDialog = false;
            state.uploadOkFiles = [];
            state.selectUploadFiles = [];
        }
        function showUpload() {
            if (utils.empty(props.folderId)) {
                message.error("请选择要上传到的文件夹");
                return false;
            }
            state.showDialog = true;
        }
        function delFile(index: number = -1) {
            state.selectUploadFiles.splice(index, 1);
        }
        return {
            UIAuth,
            bodySize,
            ...toRefs(state),
            reUpload,
            beforeUpload,
            startUpload,
            close,
            delFile,
            showUpload
        };
    },
});
</script>

<style scoped lang="scss">
.p-upload {
    & .item {
        display: flex;
        align-items: center;
        justify-content: space-between;
    }
    & .table-action-btn {
        display: flex;
        font-size: 12px;
        & > div {
            cursor: pointer;
            color: #fff;
            padding: 3px 5px;
            border-radius: 4px;
            &:nth-child(1) {
                background-color: red;
                margin-right: 5px;
                &:hover {
                    background-color: #e80404;
                }
            }
            &:nth-child(2) {
                background-color: #f87412;
                &:hover {
                    background-color: #e26304;
                }
            }
        }
    }
}
</style>